import pytest
import os
import sys
import argparse
import subprocess
from datetime import datetime
#把测试报告生成后通过邮件发送到指定的人配置
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

# 项目根目录（根据实际结构调整，确保路径正确）
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
# 测试用例根目录
TEST_CASES_ROOT = os.path.join(PROJECT_ROOT, "api_testing")
# 报告根目录
REPORTS_ROOT = os.path.join(PROJECT_ROOT, "reports")
# 定义固定的多个收件人，用逗号分隔
FIXED_RECIPIENTS = "qiuchanghao@hycen.net,wangmin@hycen.net,dairuxia@hycen.net"  # 两个收件人邮箱

def create_report_dir(system_name: str) -> str:
    """创建测试报告目录（按系统+时间戳区分）"""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    report_dir = os.path.join(REPORTS_ROOT, system_name, timestamp)
    os.makedirs(report_dir, exist_ok=True)  # 自动创建多级目录
    return report_dir


def run_test(system_name: str, env: str = "test", generate_html: bool = True, generate_allure: bool = True):
    """
    执行指定系统的测试用例
    :param system_name: 系统名称（如"testcases"、"lemangCase"）
    :param env: 环境（test/prod，默认test）
    :param generate_html: 是否生成pytest-html报告
    :param generate_allure: 是否生成allure报告
    """
    # 1. 校验系统目录是否存在
    test_dir = os.path.join(TEST_CASES_ROOT, system_name)
    if not os.path.exists(test_dir):
        print(f"错误：系统目录不存在 → {test_dir}")
        sys.exit(1)

    # 2. 创建报告目录
    report_dir = create_report_dir(system_name)
    print(f"测试报告将保存至 → {report_dir}")

    # 3. 构建pytest命令
    cmd = [
        "pytest",
        test_dir,  # 指定测试用例目录
        "-v", "-s",  # 详细输出模式
        f"--env={env}",  # 传递环境参数（供用例读取配置）
    ]

    # 4. 添加报告参数
    html_report = os.path.join(report_dir, "pytest_report.html")
    allure_report = os.path.join(report_dir, "allure_report")
    if generate_html:
        cmd.extend(["--html", html_report, "--self-contained-html"])  # 独立HTML报告
    if generate_allure:
        cmd.extend(["--alluredir", allure_report])

    # 5. 执行命令
    print(f"\n开始执行 {system_name} 系统测试（环境：{env}）...")
    print(f"执行命令：{' '.join(cmd)}")
    result = subprocess.run(cmd, cwd=PROJECT_ROOT)  # 在项目根目录执行

    # 6. 输出结果
    if result.returncode == 0:
        print(f"\n{system_name} 系统测试执行成功！报告路径：{report_dir}")
        if generate_allure:
            print(f"查看allure报告命令：allure serve {allure_report}")
    else:
        print(f"\n{system_name} 系统测试执行失败！返回码：{result.returncode}")
    return result.returncode,report_dir# 必须返回报告目录

#邮箱配置
def send_test_report(system_name: str, report_dir: str):
    """
    发送测试报告邮件
    :param system_name: 系统名称
    :param report_dir: 报告目录路径
    """

    # 邮件配置（建议放在配置文件中）
    smtp_server = "smtp.qiye.aliyun.com"  # 邮件服务器
    smtp_port = 465  # 端口，通常587
    smtp_username = "qiuchanghao@hycen.net"  # 发件人邮箱
    smtp_password = "https://0801.com"  # 密码或授权码

    # 创建邮件对象
    msg = MIMEMultipart()
    msg['From'] = smtp_username
    msg['To'] = FIXED_RECIPIENTS  # 直接使用固定的多收件人
    msg['Subject'] = f"【测试报告】{system_name}系统测试结果"

    # 邮件正文
    body = f"""
    <p>您好，</p>
    <p>{system_name}系统测试已完成，测试报告如下：</p>
    <p>报告存放路径：{report_dir}</p>
    <p>请查收附件中的测试报告。</p>
    """
    msg.attach(MIMEText(body, 'html', 'utf-8'))

    # 添加附件（pytest-html报告）
    html_report = os.path.join(report_dir, "pytest_report.html")
    if os.path.exists(html_report):
        with open(html_report, 'rb') as f:
            part = MIMEApplication(f.read(), Name="pytest_report.html")
            part['Content-Disposition'] = f'attachment; filename="pytest_report.html"'
            msg.attach(part)

    # 发送邮件
    try:
        with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:  # 阿里云465端口用SMTP_SSL
            server.login(smtp_username, smtp_password)
            server.send_message(msg)
        print(f"测试报告已发送至：{FIXED_RECIPIENTS}")
    except Exception as e:
        print(f"邮件发送失败：{str(e)}")


if __name__ == "__main__":
    # 解析命令行参数（支持指定系统、环境、报告类型）
    parser = argparse.ArgumentParser(description="执行测试用例（支持多系统）")
    parser.add_argument(
        "--system",
        type=str,
        required=False,
        choices=["testcases","lemangCase"],# 支持的系统列表
        nargs='+',# 关键：允许传入多个值（至少1个）
        default=["testcases"],
        help="指定要执行的系统（testcases/lemangCase）"
    )
    parser.add_argument(
        "--env",
        type=str,
        default="test",
        choices=["test", "prod"],
        help="指定环境（test/prod，默认test）"
    )
    parser.add_argument(
        "--no-html",
        action="store_true",
        help="不生成html报告"
    )
    parser.add_argument(
        "--no-allure",
        action="store_true",
        help="不生成allure报告"
    )
    # 解析参数
    args = parser.parse_args()
    # 遍历所有传入的 system 值，并获取索引
    for system in args.system:
        # 修正：只调用一次 run_test，接收返回值
        ret_code, report_dir = run_test(
            system_name=system,
            env=args.env,
            generate_html=not args.no_html,
            generate_allure=not args.no_allure
        )
        # 修正：调用 send_test_report 时参数匹配
        send_test_report(
            system_name=system,
            report_dir=report_dir
        )
